package com.tarena.lbs.activity.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tarena.lbs.activity.api.pojo.ActivityDto;
import com.tarena.lbs.activity.dao.repository.ActivityRepository;
import com.tarena.lbs.activity.enums.ActivityStatusEnum;
import com.tarena.lbs.activity.pojo.param.ActivityAddParam;
import com.tarena.lbs.activity.pojo.po.ActivityPO;
import com.tarena.lbs.activity.pojo.query.ActivityQuery;
import com.tarena.lbs.activity.pojo.vo.ActivityVO;
import com.tarena.lbs.activity.service.ActivityService;
import com.tarena.lbs.attach.api.AttachApi;
import com.tarena.lbs.base.common.utils.Asserts;
import com.tarena.lbs.base.protocol.exception.BusinessException;
import com.tarena.lbs.base.protocol.pager.PageResult;
import com.tarena.lbs.common.principle.UserPrinciple;
import com.tarena.lbs.common.utils.AuthenticationContextUtils;
import com.tarena.lbs.user.api.UserApi;
import com.tarena.lbs.user.api.pojo.dto.AdminDto;
import com.tarena.lbs.user.api.pojo.dto.UserDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Slf4j
@Service
public class ActivityServiceImpl implements ActivityService {
    @Autowired
    private ActivityRepository activityRepository;

    @DubboReference
    private UserApi userApi;

    @DubboReference
    private AttachApi attachApi;

    /**
     * 条件分页查询商家活动列表业务
     * @param activityQuery 查询条件
     * @return 页面对象
     */
    @Override
    public PageResult<ActivityVO> pageList(ActivityQuery activityQuery) throws BusinessException {
        log.debug("商家活动列表业务：activityQuery={}", activityQuery);
        // 身份验证
        UserPrinciple userPrinciple = AuthenticationContextUtils.get();
        Asserts.isTrue(userPrinciple == null, new BusinessException("401","身份验证失败"));
//        // 获取当前商家信息，填补到查询条件中
        AdminDto admin = userApi.getAdminById(userPrinciple.getId());
        activityQuery.setBusinessId(admin.getBusinessId());
        Page<ActivityPO> activityPOPage = activityRepository.pageList(activityQuery);
        List<ActivityVO> activityVOS = new ArrayList<>();
        activityPOPage.getRecords().forEach(activityPO -> {
            ActivityVO activityVO = new ActivityVO();
            BeanUtils.copyProperties(activityPO,activityVO);
            activityVOS.add(activityVO);
        });
        PageResult<ActivityVO> activityVOPageResult = new PageResult<>();
        activityVOPageResult.setObjects(activityVOS);
        activityVOPageResult.setPageNo((int)activityPOPage.getCurrent());
        activityVOPageResult.setPageSize((int)activityPOPage.getSize());
        activityVOPageResult.setTotal(activityPOPage.getTotal());
        return activityVOPageResult;
    }

    /**
     * 商家活动保存（新建 | 编辑）
     * @param param 活动参数
     */
    @Override
    @CacheEvict(value = "activityDetail",key = "#param.id")
    public void activitySave(ActivityAddParam param) throws BusinessException {
        log.debug("商家活动保存业务：ActivityAddParam={}",param);
        //1.验证用户身份
        UserPrinciple userPrinciple = AuthenticationContextUtils.get();
        Asserts.isTrue(userPrinciple == null, new BusinessException("401","身份验证失败"));
        //2.查询商家信息，判断商家是否存在
        AdminDto admin = userApi.getAdminById(userPrinciple.getId());
        Asserts.isTrue(admin.getAccountType() == 0, new BusinessException("299", "管理员无法添加活动"));
        //3.保存活动信息
        ActivityPO activityPO = new ActivityPO();
        BeanUtils.copyProperties(param,activityPO);
        activityPO.setBusinessId(admin.getBusinessId());
        activityPO.setStatus(ActivityStatusEnum.UNSTART.getCode());
        activityPO.setEnableStatus(0);
        if (activityPO.getId() == null){
            activityRepository.insertActivity(activityPO);
        }else {
            activityRepository.updateActivity(activityPO);
        }
        //4.通过dubbo调用附件服务 AttachApi 绑定活动和图片

    }


    /**
     * 商家活动详情业务方法
     * @param id 活动id
     * @return 活动vo
     * @throws BusinessException
     */
    @Override
    @Cacheable(value = "activityDetail",key = "#id")
    public ActivityVO activityDetail(Integer id) throws BusinessException {
        log.debug("商家活动详情业务：id={}",id);
        //1.验证用户身份
        UserPrinciple userPrinciple = AuthenticationContextUtils.get();
        Asserts.isTrue(userPrinciple == null, new BusinessException("401","身份验证失败"));
        //数据库查询活动信息
        ActivityPO activityPO = activityRepository.activityDetail(id);
        Asserts.isTrue(activityPO==null,new BusinessException("299","活动不存在"));
        //验证权限：此活动是否是当前登录商家的活动
//        Asserts.isTrue(activityPO.getBusinessId()!=admin.getBusinessId(),new BusinessException("403","无操作权限"));
        ActivityVO activityVO = new ActivityVO();
        BeanUtils.copyProperties(activityPO,activityVO);
        //调用附件服务获取活动图片并替换
        return activityVO;
    }

    /**
     * 删除活动业务
     * @param id 活动id
     * @throws BusinessException
     */
    @Override
    public void activityDelete(Integer id) throws BusinessException {
        log.debug("商家活动删除业务：id={}",id);
        //1.验证用户身份
        UserPrinciple userPrinciple = AuthenticationContextUtils.get();
        Asserts.isTrue(userPrinciple == null, new BusinessException("401","身份验证失败"));
        AdminDto admin = userApi.getAdminById(userPrinciple.getId());
        //查询是否存在这个活动
        ActivityPO activityPO = activityRepository.activityDetail(id);
        Asserts.isTrue(activityPO==null,new BusinessException("299","活动不存在"));
        //验证权限：此活动是否是当前登录商家的活动
        Asserts.isTrue(activityPO.getBusinessId()!=admin.getBusinessId(),new BusinessException("403","无操作权限"));
        //检查活动状态
        Asserts.isTrue(activityPO.getStatus() != ActivityStatusEnum.UNSTART.getCode(),new BusinessException("401","活动进行中或已删除"));
        //删除活动（更新状态为“已删除”）
        activityPO.setStatus(ActivityStatusEnum.DELETED.getCode());
        activityRepository.updateActivity(activityPO);
    }

    /**
     * 判断用户是否可以参与此活动业务
     * @param userId 用户id
     * @param activityId 活动id
     * @return
     */
    @Override
    public Boolean activityVisible(Integer userId, Integer activityId) throws BusinessException {
        log.debug("判断用户是否可以参与此活动业务：userId={}, activityId={}",userId,activityId);
        //校验活动是否存在
        ActivityPO activityPO = activityRepository.activityDetail(activityId);
        Asserts.isTrue(activityPO==null, new BusinessException("299","活动不存在"));
        //判断活动的目标人群 是否为空
        String targetCustomer = activityPO.getTargetCustomer();
        if (targetCustomer==null || targetCustomer.isEmpty()){
            return true;
        }
        //获取用户信息，获取用户所属人群
        UserDto user = userApi.getUserById(userId);
        Asserts.isTrue(user==null,new BusinessException("298","用户不存在"));
        List<Integer> userGroupIds = userApi.getUserGroupIds(user.getId(), activityPO.getBusinessId());
        //判断活动目标人群是否在用户所属人群范围内
        List<Integer> activityTargetGroupIds = Arrays.stream(targetCustomer.split(","))
                .map(Integer::parseInt)
                .toList();
        //判断是否有交集
        List<Integer> intersection = new ArrayList<>(userGroupIds);
        intersection.retainAll(activityTargetGroupIds);
        if (!intersection.isEmpty()){//有交集，说明用户在活动目标范围内
            return true;
        }
        return false;
    }

    @Override
    public ActivityDto getActivityById(Integer activityId) throws BusinessException {
        ActivityPO activityPO = activityRepository.activityDetail(activityId);
        Asserts.isTrue(activityPO==null,new BusinessException("299","活动不存在"));
        ActivityDto activityDto = new ActivityDto();
        BeanUtils.copyProperties(activityPO,activityDto);
        return activityDto;
    }
}
